package com.sm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sm.controller.request.CancelCourseReq;
import com.sm.controller.request.SelectCourseRequest;
import com.sm.controller.request.StudentRegisterReq;
import com.sm.controller.request.UpdateProfileRequest;
import com.sm.dao.CourseMapper;
import com.sm.dao.StudentMapper;
import com.sm.dao.UserMapper;
import com.sm.entity.Course;
import com.sm.entity.CourseScore;
import com.sm.entity.Student;
import com.sm.entity.User;
import com.sm.exception.CodeEnum;
import com.sm.service.StudentService;
import com.sm.utils.SaTokenUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author Cola
 * @description
 * @date 2022/1/30
 */
@Service
public class StudentServiceImpl implements StudentService {

    @Resource
    UserMapper userMapper;

    @Resource
    CourseMapper courseMapper;

    @Resource
    StudentMapper studentMapper;

    private static final int COURSE_NOT_SELECTED = 0;
    private static final int COURSE_EXIST = 1;

    @Override
    public void updateProfile(UpdateProfileRequest updateProfileRequest) {
        Integer userId = SaTokenUtils.getUserId();
        userMapper.updateProfile(userId, updateProfileRequest);
    }

    @Override
    public PageInfo<Course> getCourseListForSelect(Integer page, Integer size) {
        PageHelper.startPage(page, size);
        return new PageInfo<>(courseMapper.getCourseListForSelect());
    }

    @Override
    public List<Course> getSelectedCourseList(Integer page, Integer size) {
        Integer studentId = SaTokenUtils.getUserId();
        PageHelper.startPage(page, size);
        return courseMapper.getSelectedCourseList(studentId);
    }

    @Override
    public int getCoursesNum() {
        QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
        return courseMapper.selectCount(queryWrapper);
    }

    @Override
    public int getSelectedCoursesNum() {
        Integer studentId = SaTokenUtils.getUserId();
        return courseMapper.getSelectedCoursesNum(studentId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void selectCourse(SelectCourseRequest selectCourseRequest) throws Exception {
        Integer courseId = selectCourseRequest.getCourseId();
        // 检查选中的课程是否存在于课程列表中
        int isCourseExist = courseMapper.checkCourseExist(courseId);
        CodeEnum.course_not_exist.assertIsEquals(isCourseExist, COURSE_EXIST);
        Integer userId = SaTokenUtils.getUserId();
        // 选课人数未满，才能进行选课
        Integer maxStuNumInCourse = courseMapper.getCourseMaxNum(courseId);
        Integer stuNumInCourse = courseMapper.getCourseNum(courseId);
        if (stuNumInCourse.equals(maxStuNumInCourse)) {
            CodeEnum.course_already_full.throwException();
        }
        // 已经选课就不能再选了
        int courseStatus = courseMapper.getSelectStatus(courseId, userId);
        CodeEnum.course_already_select.assertIsEquals(courseStatus, COURSE_NOT_SELECTED);

        courseMapper.selectCourse(courseId, userId);
        courseMapper.updateSelectedNum(courseId, 1);

    }

    @Override
    public void cancelSelectCourse(CancelCourseReq req) throws Exception {
        Integer courseId = req.getCourseId();
        Integer studentId = SaTokenUtils.getUserId();
        courseMapper.cancelSelectCourse(courseId,studentId);
        courseMapper.updateSelectedNum(courseId, -1);
    }

    @Override
    public List<CourseScore> getCourseScores() {
        Integer studentId = SaTokenUtils.getUserId();
        return courseMapper.getCourseScores(studentId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void studentRegister(StudentRegisterReq req) throws Exception {
        User user = buildUserForStudnetRegister(req);
        Student student = buildStudentForRegister(req);

        // 检查注册的用户名是否已存在
        String usernameInReq = user.getUsername();
        User userInDB = userMapper.getUserByUserName(usernameInReq);
        if(userInDB!=null){
            CodeEnum.account_already_exist.assertIsNotNull(null);
        }

        userMapper.insert(user);
        student.setUserId(user.getId());
        studentMapper.insert(student);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteStuAccount() throws Exception {
        Integer userId = SaTokenUtils.getUserId();
        String username = userMapper.getUsernameById(userId);

        userMapper.deleteById(userId);
        studentMapper.deleteStu(userId);
    }

    User buildUserForStudnetRegister(StudentRegisterReq req){
        User user = new User();
        user.setUsername(req.getUsername());
        user.setPassword(req.getPassword());
        user.setAddress(req.getAddress());
        user.setPhone(req.getPhone());
        user.setGender(req.getGender());
        user.setRealName(req.getName());
        user.setRole("student");
        return user;
    }

    Student buildStudentForRegister(StudentRegisterReq req){
        Student student = new Student();
        student.setAddress(req.getAddress());
        student.setEmergencyPhone(req.getEmergencyPhone());
        student.setEmergencyContact(req.getEmergencyContact());
        student.setName(req.getName());
        student.setClassName(req.getClassName());
        student.setEnrollmentYear(req.getEnrollYear());
        student.setPhone(req.getPhone());
        student.setUsername(req.getUsername());
        return student;
    }


}
